home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of ixemul.library for the Amiga.
- * Copyright (C) 1991, 1992 Markus M. Wild
- * Portions Copyright (C) 1994 Rafael W. Luebbert
- * Portions Copyright (C) 1995 Jeff Shepherd
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: ix_startup.c,v 1.5 1994/06/19 15:13:22 rluebbert Exp $
- *
- * $Log: ix_startup.c,v $
- * Revision 1.5 1994/06/19 15:13:22 rluebbert
- * *** empty log message ***
- *
- * Revision 1.3 1992/08/09 20:55:51 amiga
- * import sysbase
- *
- * Revision 1.2 1992/07/04 19:18:21 mwild
- * remove SIGWINCH handler before returning
- *
- * Revision 1.1 1992/05/14 19:55:40 mwild
- * Initial revision
- *
- */
-
- #define _KERNEL
- #include "ixemul.h"
- #include <sys/wait.h>
- #include "kprintf.h"
-
- /* this just jumps right back into ix_startup() */
-
-
- /*
- * Note: I kept the partition into startup and _main(), although in this
- * case, both functions could be done in one function, since this is
- * a library, and the user can't override _main anyway but globally...
- */
-
- int
- ix_startup (char *aline, int alen,
- int expand, char *wb_default_window, u_int main, int *real_errno)
- {
- struct Process *me = (struct Process *) SysBase->ThisTask;
- int exit_val;
- struct WBStartup *wb_msg = NULL;
- int fd;
-
- /*
- * The following code to reset the fpu might not be necessary, BUT since
- * a CLI shell doesn't spawn a new process when executing a command - it
- * insteads calls the command like a subroutine - it depends on the Shell
- * whether the fpu is setup correctly. And I don't like to depend on any
- * thing ;-)
- */
-
- if (gotanfpu())
- resetfpu();
- /* first deal with WB messages, since those HAVE to be answered properly,
- * even if we should fail later (memory, whatever..) */
-
- if (! me->pr_CLI)
- {
- /* we have been started by Workbench. Get the StartupMsg */
- WaitPort (& me->pr_MsgPort);
- wb_msg = (struct WBStartup *) GetMsg (& me->pr_MsgPort);
- /* further processing in _main () */
- }
- else
- {
- struct CommandLineInterface *cli = (void *)BADDR(me->pr_CLI);
- long segs;
-
- /* for usage by sys_exit() for example */
- KPRINTF (("CLI command line '%s'\n", aline));
- u.u_argline = aline;
- u.u_arglinelen = alen;
- segs = cli->cli_Module;
- if ((u.u_segs = (struct my_seg *)kmalloc(sizeof(struct my_seg))))
- {
- u.u_segs->segment = segs;
- u.u_segs->name = NULL;
- }
- segs <<= 2;
- u.u_start_pc = segs + 4;
- u.u_end_pc = segs + *(long *)(segs - 4) - 8;
- }
-
- u.u_expand_cmd_line = expand;
-
- /* put some AmiTCP and AS225 in here since it can't go into ix_open
- * I need a pointer to the REAL errno
- */
- if (real_errno)
- {
- u.u_errno = real_errno;
- if (u.u_ixnetbase)
- netcall(NET_set_errno, real_errno, NULL);
- }
-
- KPRINTF (("&errno = %lx\n", real_errno));
-
- exit_val = _setjmp (u.u_jmp_buf);
- if (! exit_val)
- {
- /* from now on it's safe to allow signals */
- syscall (SYS_sigsetmask, 0);
- /* the first time thru call the program */
- KPRINTF (("calling __main()\n"));
- if (me->pr_CLI)
- syscall (SYS__main, aline, alen, main);
- else
- syscall (SYS__main, wb_msg, wb_default_window, main);
- /* NORETURN */
- }
- /* in this case we came from a longjmp-call */
-
- exit_val = u.p_xstat;
-
- ix_remove_sigwinch ();
-
- /* had to move the closing of files out of ix_close(), as close() may
- actually wait for the last packet to arrive, and inside ix_close() we're
- inside Forbid, and may thus never wait! */
-
- /* close all files */
- for (fd = 0; fd < NOFILE; fd++)
- if (u.u_ofile[fd]) syscall (SYS_close, fd);
-
- /* if at all possible, free memory before entering Forbid ! (Semaphore
- problems..) */
- all_free ();
-
- /*
- * If we were traced by a debugger who got us through a ptrace 'attach',
- * we need to unlink us from our parent and to give it a signal telling
- * it that we've died.
- */
- if (u.p_pptr && u.p_pptr != (struct Process *) 1)
- {
- send_death_msg(&u);
- Permit(); /* send_death_msg did the matching Forbid() */
- }
-
- /* if started from workbench, Forbid(), since on reply WB will deallocate
- * our task... */
- if (! me->pr_CLI)
- {
- Forbid ();
- ReplyMsg ((struct Message *) wb_msg);
- }
-
- return WEXITSTATUS(exit_val);
- }
-
- void
- _exit (int retcode)
- {
- /* ignore all signals from now on */
- syscall (SYS_sigsetmask, ~0);
- u.p_xstat = W_EXITCODE(retcode, 0);
- _longjmp (u.u_jmp_buf, 1);
- }
-